import { Component, Input, OnDestroy, OnInit } from '@angular/core';
import { EzFormConfigurationValidator } from '../../utils';
import { EzFormComponent } from '../ez-form';
import { EzFormControl, EzFormControlComponent, EzFormControlConfiguration } from '../ez-form-control';
import { EzFormGroup } from './ez-form-group';
import { EzFormGroupConfiguration } from './ez-form-group.configuration';

@Component({
  selector: 'ez-form-group',
  templateUrl: './ez-form-group.component.html',
  styleUrls: ['./ez-form-group.component.less'],
})
export class EzFormGroupComponent implements EzFormGroup, OnInit, OnDestroy {
  @Input()
  ezFormGroupConfiguration: EzFormGroupConfiguration;

  ezFormControls: { [name: string]: EzFormControl } = {};

  constructor(public ezForm: EzFormComponent) {}

  ngOnInit(): void {
    this.ezForm.addEzFormGroupComponent(this.ezFormGroupConfiguration.name, this);
  }

  ngOnDestroy(): void {
    this.ezForm.removeEzFormGroupComponent(this.ezFormGroupConfiguration.name);
  }

  add(configuration: EzFormControlConfiguration, index?: number): void {
    if (index && (index < 0 || index > this.ezFormGroupConfiguration.controls.length)) {
      throw new Error(`控件插入位置参数非法`);
    }
    index = index === 0 ? 0 : index ? index : this.ezFormGroupConfiguration.controls.length;
    EzFormConfigurationValidator.validateControl(configuration);
    if (this.contains(configuration.name) || this.ezForm.containsControl(configuration.name)) {
      throw new Error(`控件${configuration.name}已经存在`);
    }
    this.ezFormGroupConfiguration.controls.splice(index, 0, configuration);
    this.ezFormGroupConfiguration.controls = [...this.ezFormGroupConfiguration.controls];
  }

  remove(name: string): void {
    if (this.contains(name)) {
      this.ezFormGroupConfiguration.controls = this.ezFormGroupConfiguration.controls.filter(item => {
        return item.name !== name;
      });
    }
  }

  get<C extends EzFormControl<any> = EzFormControl<any>>(name: string): C {
    return (this.ezFormControls[name] as C) || null;
  }

  addEzFormControlComponent(name: string, control: EzFormControlComponent): void {
    this.ezFormControls[name] = control;
  }

  removeEzFormControlComponent(name: string): void {
    delete this.ezFormControls[name];
  }

  contains(name: string): boolean {
    return !!this.ezFormGroupConfiguration.controls.find(item => item.name === name);
  }

  disable(names?: string | string[]): void {
    if (!names) {
      Object.values(this.ezFormControls).forEach(control => {
        control.disable();
      });
    } else {
      names = Array.isArray(names) ? names : [names];
      Object.keys(this.ezFormControls)
        .filter(name => names.includes(name))
        .forEach(name => {
          this.ezFormControls[name].disable();
        });
    }
  }

  enable(names?: string | string[]): void {
    if (!names) {
      Object.values(this.ezFormControls).forEach(control => {
        control.enable();
      });
    } else {
      names = Array.isArray(names) ? names : [names];
      Object.keys(this.ezFormControls)
        .filter(name => names.includes(name))
        .forEach(name => {
          this.ezFormControls[name].enable();
        });
    }
  }
}
